﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.GData.YouTube;
using System.Web.Caching;
using System.Web;
using Google.GData.Client;
using Google.YouTube;
using System.Web.SessionState;

namespace DDNY.WebPortals.Common
{
    public class YoutubeHelper
    {
        public static HttpSessionState Session
        {
            get
            {
                return HttpContext.Current.Session;
            }
        }

        public static string AccessToken
        {
            get
            {
                if (Session["access_token"] == null)
                {
                    return null;
                }
                return Session["access_token"].ToString();
            }

            set { Session["access_token"] = value; }
        }

        public const int PageSize = 20;
        public const int MaxPageSize = 50;
        public const string DefaultOrderBy = "viewCount";//rating???
        const string StandardFeedFormatString = "http://gdata.youtube.com/feeds/api/standardfeeds/{0}?v=2&start-index={1}&max-results={2}";
        const string SingleVideoFeedFormatString = "http://gdata.youtube.com/feeds/api/videos/{0}?v=2";
        const string PlaylistVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/playlists/{0}?v=2";
        const string PlayListFormatString = "https://gdata.youtube.com/feeds/api/users/{0}/playlists?v=2";
        const string CommentsForVideoFormatString = "https://gdata.youtube.com/feeds/api/videos/{0}/comments?v=2&start-index={1}&max-results={2}";
        const string PrivateFavoritesVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/users/default/favorites?v=2&access_token={0}";
        const string FavoritesVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/users/{0}/favorites";
        const string RelatedVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/videos/{0}/related?v=2";
        const string CategoryVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/videos/-/{0}/?v=2&start-index={1}&max-results={2}&orderby={3}";
        const string RecommendedVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/users/{0}/recommendations";
        const string SearchVideoFeedFormatString = "http://gdata.youtube.com/feeds/api/videos?q={0}&start-index={1}&max-results={2}&orderby={3}";
        const string UserProfileFeedFormatString = "https://gdata.youtube.com/feeds/api/users/{0}";
        const string UserUploadedVideoFeedFormatString = "https://gdata.youtube.com/feeds/api/users/{0}/uploads";
        const string UserSubscriptionsFeedFormatString = "http://gdata.youtube.com/feeds/api/users/{0}/subscriptions";
        const string VideoRatingFeedFormatString = "http://gdata.youtube.com/feeds/api/videos/{0}/ratings";


        const string clientID = "ytapi-NikolayYordanov-buzzhour-673umn97-1";
        const string developerKey = "AI39si65gkXT57qFsN8zVZiAMVRpySX9h_TVRKBS5F3bGrO0c06YuF6ISMhX2BQZyZp2MxMa_JOtcftvSeiA1kqIpzN2CulfYA";
        const string password = "dessi77&";
        const string application = "buzzhour";
        const string username = "seniordotnetdeveloper@gmail.com";
        public const string seniordotnetdeveloper = "default";
        public const string seniordotnetdevelope = "seniordotnetdevelope";

        private static YouTubeService service;

        public static Cache CurrentCache
        {
            get
            {
                return HttpContext.Current.Cache;
            }
        }


        public static YouTubeService YTService
        {
            get
            {
                if (service == null)
                {

                    service = new YouTubeService(application, developerKey);
                    service.setUserCredentials(username, password);
                }
                return service;
            }
        }

        private static YouTubeRequest request;

        public static YouTubeRequest SingleRequest
        {
            get
            {
                if (request == null)
                {
                    YouTubeRequestSettings settings =
  new YouTubeRequestSettings(application, developerKey, username, password);
                    request = new YouTubeRequest(settings);
                }
                return request;
            }
        }


        //public static Feed<YtRating> GetVideoRatings(string videoId)
        //{
        //    string feedUrl = string.Format(VideoRatingFeedFormatString, videoId);
        //    Feed<YtRating> result = SingleRequest.Get<YtRating>(new Uri(feedUrl));

        //}



        public static YouTubeFeed FindVideoByKeyWordFromYouTube(string keyword)
        {
            string username = "seniordotnetdeveloper@gmail.com";
            string password = "dessi77&";
            string application = "buzzhour";

            string developerKey = "AI39si65gkXT57qFsN8zVZiAMVRpySX9h_TVRKBS5F3bGrO0c06YuF6ISMhX2BQZyZp2MxMa_JOtcftvSeiA1kqIpzN2CulfYA";

            YouTubeService service = new YouTubeService(application, developerKey);
            service.setUserCredentials(username, password);

            YouTubeQuery query = new YouTubeQuery(YouTubeQuery.DefaultVideoUri);
            query.Query = keyword;
            query.NumberToRetrieve = 18;
            YouTubeFeed videoFeed = service.Query(query);
            return videoFeed;
        }

        public static YouTubeEntry FindVideo(string videoId)
        {
            string username = "seniordotnetdeveloper@gmail.com";
            string password = "dessi77&";
            string application = "buzzhour";

            string developerKey = "AI39si65gkXT57qFsN8zVZiAMVRpySX9h_TVRKBS5F3bGrO0c06YuF6ISMhX2BQZyZp2MxMa_JOtcftvSeiA1kqIpzN2CulfYA";

            YouTubeService service = new YouTubeService(application, developerKey);
            service.setUserCredentials(username, password);

            YouTubeQuery query = new YouTubeQuery(YouTubeQuery.DefaultVideoUri + "/" + videoId);

            try
            {
                YouTubeFeed videoFeed = service.Query(query);
                return (YouTubeEntry)videoFeed.Entries[0];
            }
            catch (Exception)
            {
                return null;
            }

        }

        public static YouTubeFeed FindVideoByKeyWord(string keyword)
        {
            keyword = CreateUsefulKeyWord(keyword);
            string cacheKey = "FindVideoByKeyWord" + keyword;
            Cache cache = HttpContext.Current.Cache;
            YouTubeFeed result = cache[cacheKey] as YouTubeFeed;
            if (result == null)
            {
                result = FindVideoByKeyWordFromYouTube(keyword);
                cache.Add(cacheKey, result, null, DateTime.MaxValue, new TimeSpan(1, 0, 0), CacheItemPriority.Normal, null);
            }
            return result;
        }

        public static List<YouTubeEntry> FindVideoEntriesByKeyWord(string keyword)
        {
            YouTubeFeed tempResult = FindVideoByKeyWord(keyword);

            List<YouTubeEntry> result = new List<YouTubeEntry>();
            foreach (var item in tempResult.Entries)
            {
                result.Add(item as YouTubeEntry);
            }
            return result;

        }

        public static string CreateUsefulKeyWord(string baseKeyWord)
        {
            string result = string.Empty;

            string[] titleWords = baseKeyWord.Split(new char[] { ' ' });
            List<string> usefulWords = new List<string>();
            foreach (string wordItem in titleWords)
            {
                if (wordItem.Length > 1)
                {
                    usefulWords.Add(wordItem);
                }
            }
            int maxNumberOfWordsToUse = 3;
            if (usefulWords.Count < maxNumberOfWordsToUse)
            {
                maxNumberOfWordsToUse = usefulWords.Count;
            }

            for (int i = 0; i < maxNumberOfWordsToUse; i++)
            {
                result += usefulWords[i] + " ";
            }

            return result;
        }

        public static YouTubeEntry GetVideoById(string videoId)
        {
            YouTubeEntry tempResult = FindVideo(videoId);


            return tempResult;
        }

        public static Feed<Video> GetFeedById(string feedId, int page)
        {
            int startIndex = page * PageSize + 1;
            string feedUrl = string.Format(StandardFeedFormatString, feedId, startIndex, PageSize);
            Feed<Video> videoFeed = null;
            string cacheKey = feedUrl;
            if (CurrentCache[cacheKey] != null)
            {
                videoFeed = (Feed<Video>)CurrentCache[cacheKey];
            }
            else
            {
                YouTubeQuery query = new YouTubeQuery();
                videoFeed = SingleRequest.Get<Video>(new Uri(feedUrl));
                CurrentCache.Add(cacheKey, videoFeed, null, DateTime.Now.AddHours(2), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);

            }



            //videoFeed = SingleRequvideoFeedideoFeed, FeedRequestType.Next);


            return videoFeed;
        }

        public static Video GetById(string videoId)
        {
            string entryUrlString = string.Format(SingleVideoFeedFormatString, videoId);

            Video video = null;
            if (CurrentCache[entryUrlString] != null)
            {
                video = (Video)CurrentCache[entryUrlString];
            }
            else
            {
                Uri videoEntryUrl = new Uri(entryUrlString);
                video = SingleRequest.Retrieve<Video>(videoEntryUrl);
                CurrentCache.Add(entryUrlString, video, null, DateTime.Now.AddHours(2), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }

            return video;
        }

        public static Feed<Video> GetUsersHistory()
        {
            string feedUrl = "https://gdata.youtube.com/feeds/api/users/default/watch_history?v=2";
            Feed<Video> result = GetFeedByUrl(feedUrl);
            return result;
        }

        public static Feed<Video> GetFavorites()
        {
            string favoritesUrl = string.Format(PrivateFavoritesVideoFeedFormatString, AccessToken);
            Uri videoFeedUri = new Uri(favoritesUrl);
            Feed<Video> result = SingleRequest.Get<Video>(videoFeedUri);
            return result;
        }

        public static Feed<Video> GetFavorites(string userId)
        {
            string favoritesUrl = string.Format(FavoritesVideoFeedFormatString, userId);
            Uri videoFeedUri = new Uri(favoritesUrl);
            Feed<Video> result = SingleRequest.Get<Video>(videoFeedUri);
            return result;
        }

        public static Feed<Video> GetFeedByUrl(string feedUrl)
        {
            Feed<Video> videoFeed = null;
            if (CurrentCache[feedUrl] != null)
            {
                videoFeed = (Feed<Video>)CurrentCache[feedUrl];
            }
            else
            {
                Uri videoFeedUri = new Uri(feedUrl);
                videoFeed = SingleRequest.Get<Video>(videoFeedUri);
                CurrentCache.Add(feedUrl, videoFeed, null, DateTime.Now.AddHours(2), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }
            return videoFeed;
        }

        public static Feed<Playlist> GetAllPlaylists()
        {
            Feed<Playlist> result = null;
            string userId = "7mD3uO_jPGIrrIeaVaPmOg";
            //userId = "cj-LJq-jp-M6zBBRkciINg";//my id
            userId = "seniordotnetdevelope";
            result = GetPlaylistsByAuthor(userId);
            return result;
        }

        public static List<YoutubeFeedType> GetMainYoutubeFeedTypes()
        {
            List<YoutubeFeedType> result = new List<YoutubeFeedType>();
           // result.Add(new YoutubeFeedType()
           // {
           //     DisplayName = "Top Rated",
           //     FeedId = "top_rated"
           // });
           // result.Add(new YoutubeFeedType()
           // {
           //     DisplayName = "Top Favorites",
           //     FeedId = "top_favorites"
           // });
           // result.Add(new YoutubeFeedType()
           //{
           //    DisplayName = "Most Watched",
           //    FeedId = "most_viewed"
           //});


           // result.Add(new YoutubeFeedType()
           // {
           //     DisplayName = "Most Shared",
           //     FeedId = "most_shared"
           // });

            result.Add(new YoutubeFeedType()
            {
                DisplayName = "Most Popular",
                FeedId = "most_popular"
            });

            //result.Add(new YoutubeFeedType()
            //{
            //    DisplayName = "Most Recent",
            //    FeedId = "most_recent"
            //});

            //result.Add(new YoutubeFeedType()
            //{
            //    DisplayName = "Most Discussed",
            //    FeedId = "most_discussed"
            //});

            //result.Add(new YoutubeFeedType()
            //{
            //    DisplayName = "Most Responded",
            //    FeedId = "most_responded"
            //});

            //result.Add(new YoutubeFeedType()
            //{
            //    DisplayName = "Recently Featured",
            //    FeedId = "recently_featured"
            //});

            //result.Add(new YoutubeFeedType()
            //{
            //    DisplayName = "Trending Videos",
            //    FeedId = "on_the_web"
            //});



            return result;
        }

        public static Feed<Video> GetVideosFromPlayList(string playListId)
        {
            string playListUrl = string.Format(PlaylistVideoFeedFormatString, playListId);
            Uri videoFeedUri = new Uri(playListUrl);
            Feed<Video> result = SingleRequest.Get<Video>(videoFeedUri);
            return result;
        }

        public static Feed<Comment> GetComments(string videoId, int page)
        {
            int startIndex = page * MaxPageSize + 1;
            Feed<Comment> result;
            string commentsUrl = string.Format(CommentsForVideoFormatString, videoId, startIndex, MaxPageSize);
            if (CurrentCache[commentsUrl] != null)
            {
                result = CurrentCache[commentsUrl] as Feed<Comment>;
            }
            else
            {
                Uri commentsFeedUri = new Uri(commentsUrl);
                result = SingleRequest.Get<Comment>(commentsFeedUri);
                CurrentCache.Add(commentsUrl, result, null, DateTime.Now.AddHours(2), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }
            return result;
        }

        public static Feed<Playlist> GetPlaylistsByAuthor(string userId)
        {
            Feed<Playlist> result = null;
            string playlistsUrl = string.Format(PlayListFormatString, userId);
            Uri playlistsUri = new Uri(playlistsUrl);
            result = SingleRequest.Get<Playlist>(playlistsUri);
            return result;
        }

        public static Feed<Video> GetRelatedVideos(string videoId)
        {
            string feedUrl = string.Format(RelatedVideoFeedFormatString, videoId);
            Feed<Video> result = GetFeedByUrl(feedUrl);
            try
            {
                int results = result.TotalResults;
            }
            catch (Exception)
            {
                result = null;
            }
            return result;
        }

        public static Feed<Video> GetVideosByTagOrCategory(string categoryOrTag, int page)
        {
            int startIndex = page * PageSize + 1;
            string feedUrl = string.Format(CategoryVideoFeedFormatString, categoryOrTag, startIndex, PageSize, DefaultOrderBy);
            Feed<Video> result = GetFeedByUrl(feedUrl);
            return result;
        }

        public static Feed<Video> GetRecommendedVideos(string userId)
        {
            userId = "default";
            string feedUrl = string.Format(RecommendedVideoFeedFormatString, userId);
            Feed<Video> result = GetFeedByUrl(feedUrl);
            return result;
        }


        public static Feed<Video> SearchVideos(string keyword, int page)
        {
            int startIndex = page * PageSize + 1;
            string feedUrl = string.Format(SearchVideoFeedFormatString, keyword, startIndex, PageSize, DefaultOrderBy);
            Feed<Video> result = GetFeedByUrl(feedUrl);
            return result;
        }

        public static ProfileEntry GetUserInfo(string userName)
        {
            string feedUrl = string.Format(UserProfileFeedFormatString, userName);
            ProfileEntry result;
            if (CurrentCache[feedUrl] != null)
            {
                var entry = CurrentCache[feedUrl];
                result = entry as ProfileEntry;
            }
            else
            {
                Uri videoFeedUri = new Uri(feedUrl);
                var entry = SingleRequest.Service.Get(feedUrl);
                result = entry as ProfileEntry;
                CurrentCache.Add(feedUrl, result, null, DateTime.Now.AddHours(2), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }
            return result;
            
        }

        public static Feed<Video> GetUploadedVideos(string userId)
        {
            string favoritesUrl = string.Format(UserUploadedVideoFeedFormatString, userId);
            Feed<Video> result = GetFeedByUrl(favoritesUrl);
            return result;
        }

        public static Feed<Subscription> GetUserSubscriptions(string userId)
        {

            string feedUrl = string.Format(UserSubscriptionsFeedFormatString, userId);

            Feed<Subscription> subFeed;
            if (CurrentCache[feedUrl] != null)
            {
                subFeed = (Feed<Subscription>)CurrentCache[feedUrl];
            }
            else
            {
                subFeed = SingleRequest.GetSubscriptionsFeed(userId);
                CurrentCache.Add(feedUrl, subFeed, null, DateTime.Now.AddHours(2), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }
            return subFeed;
        }



    }
}
